/**
 * FileName:Exercise1402.c
 * ------------------------------------------------------------------------------------------------------------
 * 14.2 Check whether there is any execution-time overhead in converting from a 4-byte key to a 32-bit integer
 * in your programming environment.
 * ------------------------------------------------------------------------------------------------------------
 */


#include <stdio.h>
#include <stdlib.h> // For rand(), srand(), malloc(), free()
#include <time.h>   // For clock(), time()
#include <stdint.h> // For uint32_t, uint8_t, uint64_t
#include <string.h> // For memcpy

#define NUM_INTEGERS 100000 // 10万个整数
#define NUM_BYTES (NUM_INTEGERS * 4) // 对应40万个字节

// 为了更好的随机数生成，尤其是在需要32位随机数时
// rand() 通常只返回 0 到 RAND_MAX (通常是 32767)
// 我们需要确保生成的是完整的32位随机数
uint32_t get_random_uint32() {
    uint32_t r = 0;
    // 组合多个 rand() 调用来填充32位
    // 假设 RAND_MAX >= 32767
    r = ( (uint32_t)rand() << 16) | ( (uint32_t)rand() & 0xFFFF );
    return r;
}

int main() {
    // --- 随机数生成初始化 ---
    srand(time(NULL)); // 使用当前时间作为随机数种子

    // --- 准备数据：10万个原始的32位整数 ---
    uint32_t* original_integer_array = (uint32_t*)malloc(NUM_INTEGERS * sizeof(uint32_t));
    if (original_integer_array == NULL) {
        perror("Failed to allocate memory for original_integer_array");
        return 1;
    }

    // 填充原始随机整数
    for (int i = 0; i < NUM_INTEGERS; i++) {
        original_integer_array[i] = get_random_uint32();
    }

    // --- 第一部分：基准测试 (直接对原始32位整数数组求和) ---
    uint64_t sum_integers_direct = 0; // 使用uint64_t防止求和溢出
    clock_t start_time, end_time;
    double cpu_time_used;

    printf("--- Benchmarking direct summation of original 32-bit integers ---\n");
    start_time = clock();
    for (int i = 0; i < NUM_INTEGERS; i++) {
        sum_integers_direct += original_integer_array[i];
    }
    end_time = clock();
    cpu_time_used = ((double)(end_time - start_time)) / CLOCKS_PER_SEC;
    printf("Sum of %d original integers: %llu\n", NUM_INTEGERS, sum_integers_direct);
    printf("Time taken for direct integer summation: %f seconds\n", cpu_time_used);

    // --- 第二部分：分解、转换并求和测试 ---
    // 根据原始整数数组分解生成40万个单字节数据
    uint8_t* byte_array = (uint8_t*)malloc(NUM_BYTES * sizeof(uint8_t));
    if (byte_array == NULL) {
        perror("Failed to allocate memory for byte_array");
        free(original_integer_array);
        return 1;
    }

    // 将每个32位整数分解为4个字节
    // 注意：这里的分解会受到系统字节序的影响。
    // 如果系统是小端序，val的低位字节会放在byte_array的前面。
    // 如果系统是大端序，val的高位字节会放在byte_array的前面。
    // 这与后续 memcpy 的行为是匹配的，因此求和结果仍然一致。
    memcpy(byte_array, original_integer_array, NUM_BYTES);


    uint64_t sum_converted_integers = 0;

    printf("\n--- Benchmarking 4-byte to 32-bit conversion and summation (using memcpy) ---\n");
    start_time = clock();
    for (int i = 0; i < NUM_INTEGERS; i++) {
        uint32_t converted_val;
        // 从字节数组中读取4个字节并转换为32位整数
        memcpy(&converted_val, &byte_array[i * 4], sizeof(uint32_t));
        sum_converted_integers += converted_val;
    }
    end_time = clock();
    cpu_time_used = ((double)(end_time - start_time)) / CLOCKS_PER_SEC;
    printf("Sum of %d converted integers: %llu\n", NUM_INTEGERS, sum_converted_integers);
    printf("Time taken for conversion and summation: %f seconds\n", cpu_time_used);

    // 验证求和结果是否一致（理论上应该一致，除非有溢出或逻辑错误）
    if (sum_integers_direct == sum_converted_integers) {
        printf("\nVerification: Sums match (0x%llX == 0x%llX).\n", sum_integers_direct, sum_converted_integers);
    } else {
        printf("\nVerification: Sums MISMATCH! This might indicate a problem (0x%llX != 0x%llX).\n", sum_integers_direct, sum_converted_integers);
    }


    // --- 释放所有分配的内存 ---
    free(original_integer_array);
    free(byte_array); // 释放第二次malloc的内存

    return 0;
}